#region Using References

using System.IO;

#endregion

namespace Beaker.OpenCube.Specs.Builders
{
	/// <summary>
	/// A Stream decorator that allowes a stream to be configured for reading, writing and seeking
	/// </summary>
	public class ConfigurableStream
		: Stream
	{
		private readonly Stream _actualStream;
		private bool _canSeek = true;
		private bool _canWrite = true;
		private bool _canRead = true;

		public ConfigurableStream( Stream actualStream )
		{
			_actualStream = actualStream;
		}

		public override void Flush()
		{
			_actualStream.Flush();
		}

		public override long Seek( long offset, SeekOrigin origin )
		{
			if( _canSeek == false )
				throw new IOException( "Seeking has been disabled" );

			return _actualStream.Seek( offset, origin );
		}

		public override void SetLength( long value )
		{
			if( _canWrite == false )
				throw new IOException( "Writing has been disabled" );

			_actualStream.SetLength( value );
		}

		public override int Read( byte[] buffer, int offset, int count )
		{
			if( _canWrite == false )
				throw new IOException( "Reading has been disabled" );

			return _actualStream.Read( buffer, offset, count );
		}

		public override void Write( byte[] buffer, int offset, int count )
		{
			if( _canWrite == false )
				throw new IOException( "Writing has been disabled" );

			_actualStream.Write( buffer, offset, count );
		}

		public override bool CanRead
		{
			get { return _canRead; }
		}

		public void DisableReading()
		{
			_canRead = false;
		}

		public void EnableReading()
		{
			_canRead = true;
		}

		public override bool CanSeek
		{
			get { return _canSeek; }
		}

		public void DisableSeeking()
		{
			_canSeek = false;
		}

		public void EnableSeeking()
		{
			_canSeek = true;
		}

		public override bool CanWrite
		{
			get { return _canWrite; }
		}

		public void DisableWriting()
		{
			_canWrite = false;
		}

		public void EnableWriting()
		{
			_canWrite = true;
		}

		public override long Length
		{
			get { return _actualStream.Length; }
		}

		public override long Position
		{
			get { return _actualStream.Position; }
			set
			{
				if( _canWrite == false )
					throw new IOException();

				_actualStream.Position = value;
			}
		}
	}
}